#include "sfrworker.h"
#include <visionavadaptor.h>
//#include "aacorenew.h"
#include <QElapsedTimer>
#include <QImage>
#include <QPainter>
#include "aacore.h"

void SfrWorker::doWork(unsigned int index, double z, cv::Mat img, int max_intensity, int min_area, int max_area, int freq_factor, int selectedLayer)
{
    QElapsedTimer timer;
    timer.start();
    vector<Sfr_entry> sv_result;
    {
        std::vector<MTF_Pattern_Position> vec;
        std::vector<MTF_Pattern_Position> result_vec;

        double imageCenterX = img.cols/2;
        double imageCenterY = img.rows/2;
        double r1 = sqrt(imageCenterX*imageCenterX + imageCenterY*imageCenterY);
        double patterns_x[20], patterns_y[20], patterns_area[20];
        int patterns_layer[20];
        int pattern_size = 0;
        AA_Helper::AAA_Search_MTF_Pattern_Simple(img, max_intensity, min_area, max_area, -1, pattern_size, patterns_x, patterns_y, patterns_layer, patterns_area);

        if (pattern_size == 0) {
            qInfo("Cannot find any mtf pattern. Sfr calculation fail");
            emit sfrResultsReady(index, std::move(sv_result), 0);
            return;
        }

        for (uint i = 0; i < pattern_size; i++) {
            //Crop ROI
            {
                cv::Rect roi; cv::Mat copped_roi;
                double width = sqrt(patterns_area[i])/2;
                roi.width = width*4; roi.height = width*4;
                roi.x = patterns_x[i] - width*2;
                roi.y = patterns_y[i] - width*2;
                if (roi.x < 0) roi.x = 0;
                if (roi.x + roi.width > img.cols) { roi.width = img.cols - roi.x; }
                if (roi.y < 0) roi.y = 0;
                if (roi.y + roi.height > img.rows) { roi.height = img.rows - roi.y; }

                img(roi).copyTo(copped_roi);
                double radius = sqrt(pow(patterns_x[i] - imageCenterX, 2) + pow(patterns_y[i] - imageCenterY, 2));
                double f = radius/r1;
                double t_sfr = 0, r_sfr = 0, b_sfr = 0, l_sfr = 0;
                sfr::sfr_calculation_single_pattern(copped_roi, t_sfr, r_sfr, b_sfr, l_sfr, 8*freq_factor);
//                double avg_sfr = l_sfr;// = ( t_sfr + r_sfr + b_sfr + l_sfr)/4;
//                if (i == 1 || i ==2)
//                    avg_sfr = r_sfr;
                double avg_sfr = ( t_sfr + r_sfr + b_sfr + l_sfr)/4;
                vec.emplace_back(patterns_x[i], patterns_y[i],
                                 f, t_sfr*100, r_sfr*100, b_sfr*100, l_sfr*100,
                                 patterns_area[i], avg_sfr*100);
                vec[i].layer = patterns_layer[i];
            }
        }

        for (int i = 0; i < vec.size(); i++) {
            if (vec[i].layer <= selectedLayer) {
                result_vec.push_back(vec[i]);
            }
        }

        for (int i = 0; i < result_vec.size(); i++) {
            qInfo("Detected result layer: %d x: %f y: %f . User Selected layer: %d", result_vec[i].layer, result_vec[i].x, result_vec[i].y, selectedLayer);
        }

        Sfr_entry entry = Sfr_entry(result_vec[0].x, result_vec[0].y, z, result_vec[0].avg_sfr, result_vec[0].area,
                result_vec[0].t_sfr, result_vec[0].r_sfr, result_vec[0].b_sfr, result_vec[0].l_sfr, result_vec[0].layer, 0);
        sv_result.push_back(entry);

        for (size_t i = 1; i < result_vec.size(); i++) {
            int location = 1;
            if ( (result_vec[i].x < imageCenterX) && (result_vec[i].y < imageCenterY))
            {
                location = 1; //UL
            } else if ((result_vec[i].x > imageCenterX) && (result_vec[i].y < imageCenterY))
            {
                location = 2; //UR
            } else if ((result_vec[i].x > imageCenterX) && (result_vec[i].y > imageCenterY))
            {
                location = 3; //LR
            } else if ((result_vec[i].x < imageCenterX) && (result_vec[i].y > imageCenterY))
            {
                location = 4; //LL
            }
            Sfr_entry entry = Sfr_entry(result_vec[i].x, result_vec[i].y, z, result_vec[i].avg_sfr, result_vec[i].area,
                                        result_vec[i].t_sfr, result_vec[i].r_sfr, result_vec[i].b_sfr, result_vec[i].l_sfr, result_vec[i].layer, location);
            sv_result.push_back(entry);
        }
    }

    if (sv_result.size() == 0) {
        qInfo("Cannot find any mtf pattern. Sfr calculation fail");
        emit sfrResultsReady(index, std::move(sv_result), 0);
        return;
    }

    emit sfrResultsReady(index, std::move(sv_result), timer.elapsed());
}

SfrWorkerController::SfrWorkerController(AACore *a)
{
    std::vector<Sfr_entry> sfr_v;
    worker = new SfrWorker();
    worker->moveToThread(&workerThread);
    connect(this, &SfrWorkerController::calculate, worker, &SfrWorker::doWork);
    connect(worker, &SfrWorker::sfrResultsReady, a, &AACore::storeSfrResults, Qt::DirectConnection);
    workerThread.start();
}

SfrWorkerController::~SfrWorkerController()
{
    workerThread.quit();
    workerThread.wait();
}
